'use client'; import * as React from 'react'; import { useState, useTransition } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { Loader2, Search, User, Building2 } from 'lucide-react'; import { searchUsers, getUserVendorInfo, getVendorList, changeVendor } from '@/lib/change-vendor/service'; import { toast } from 'sonner'; interface User { id: number; name: string; email: string; companyId: number | null; } interface UserVendorInfo { userId: number; userName: string; userEmail: string; currentVendorId: number | null; currentVendorName: string | null; currentVendorCode: string | null; } interface Vendor { id: number; vendorName: string; vendorCode: string | null; status: string; } export function ChangeVendorClient() { const [isPending, startTransition] = useTransition(); const [isSearchingUsers, setIsSearchingUsers] = React.useState(false); const [isSearchingVendors, setIsSearchingVendors] = React.useState(false); const [isLoadingVendorInfo, setIsLoadingVendorInfo] = React.useState(false); const [userSearchQuery, setUserSearchQuery] = useState(''); const [users, setUsers] = useState([]); const [selectedUserId, setSelectedUserId] = useState(null); const [userVendorInfo, setUserVendorInfo] = useState(null); const [vendorSearchQuery, setVendorSearchQuery] = useState(''); const [vendors, setVendors] = useState([]); const [selectedVendorId, setSelectedVendorId] = useState(''); const [error, setError] = useState(null); // 유저 검색 const handleSearchUsers = async () => { if (isSearchingUsers) return; setIsSearchingUsers(true); setError(null); setSelectedUserId(null); setUserVendorInfo(null); setSelectedVendorId(''); try { const result = await searchUsers(userSearchQuery); if (result.error) { setError(result.error); return; } setUsers(result.data || []); if (result.data && result.data.length === 0) { toast.info('검색 결과가 없습니다.'); } } catch (err) { setError('유저 검색 중 오류가 발생했습니다.'); console.error(err); } finally { setIsSearchingUsers(false); } }; // 유저 검색어 입력 시 엔터키 처리 const handleUserSearchKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleSearchUsers(); } }; // 유저 선택 시 해당 유저의 벤더 정보 조회 const handleUserSelect = async (userId: number) => { setSelectedUserId(userId); setUserVendorInfo(null); setSelectedVendorId(''); setIsLoadingVendorInfo(true); setError(null); try { const result = await getUserVendorInfo(userId); if (result.error) { setError(result.error); return; } setUserVendorInfo(result.data); // 벤더 목록도 함께 로드 await loadVendors(); } catch (err) { setError('유저 정보를 불러오는 중 오류가 발생했습니다.'); console.error(err); } finally { setIsLoadingVendorInfo(false); } }; // 벤더 목록 로드 const loadVendors = async () => { setIsSearchingVendors(true); try { const result = await getVendorList(vendorSearchQuery); if (result.error) { setError(result.error); return; } setVendors(result.data || []); } catch (err) { setError('벤더 목록을 불러오는 중 오류가 발생했습니다.'); console.error(err); } finally { setIsSearchingVendors(false); } }; // 벤더 검색 const handleSearchVendors = async () => { if (isSearchingVendors) return; setIsSearchingVendors(true); setError(null); setSelectedVendorId(''); try { const result = await getVendorList(vendorSearchQuery); if (result.error) { setError(result.error); return; } setVendors(result.data || []); if (result.data && result.data.length === 0) { toast.info('검색 결과가 없습니다.'); } } catch (err) { setError('벤더 검색 중 오류가 발생했습니다.'); console.error(err); } finally { setIsSearchingVendors(false); } }; // 벤더 검색어 입력 시 엔터키 처리 const handleVendorSearchKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleSearchVendors(); } }; // 벤더 변경 처리 const handleChangeVendor = () => { if (!selectedUserId) { toast.error('유저를 선택해주세요.'); return; } if (!selectedVendorId) { toast.error('변경할 벤더를 선택해주세요.'); return; } const vendorId = Number(selectedVendorId); if (userVendorInfo?.currentVendorId === vendorId) { toast.error('현재 선택된 벤더와 동일합니다.'); return; } startTransition(async () => { try { const result = await changeVendor(selectedUserId, vendorId); if (result.error || !result.success) { toast.error(result.error || '벤더 변경에 실패했습니다.'); return; } toast.success(`"${result.data?.userName}"님의 벤더가 "${result.data?.vendorName}"로 변경되었습니다.`); // 유저 정보 새로고침 await handleUserSelect(selectedUserId); } catch (err) { toast.error('벤더 변경 중 오류가 발생했습니다.'); console.error(err); } }); }; return (
{/* 1단계: 유저 검색 및 선택 */} 유저 검색 및 선택 벤더를 변경할 유저를 검색하고 선택하세요. {/* 유저 검색 */}
setUserSearchQuery(e.target.value)} onKeyDown={handleUserSearchKeyDown} disabled={isSearchingUsers} />
{/* 유저 선택 */} {users.length > 0 && (
)} {isLoadingVendorInfo && (
)} {/* 선택한 유저의 현재 벤더 정보 */} {userVendorInfo && (
{userVendorInfo.userName}
{userVendorInfo.userEmail}
{userVendorInfo.currentVendorName || '벤더 정보 없음'} {userVendorInfo.currentVendorCode && ( ({userVendorInfo.currentVendorCode}) )}
)}
{/* 2단계: 벤더 검색 및 선택 (유저 선택 후에만 표시) */} {selectedUserId && userVendorInfo && ( 벤더 변경 변경할 벤더를 검색하고 선택하세요. {/* 벤더 검색 */}
setVendorSearchQuery(e.target.value)} onKeyDown={handleVendorSearchKeyDown} disabled={isSearchingVendors} />
{/* 벤더 선택 */} {vendors.length > 0 && (
)} {error && ( {error} )} {/* 저장 버튼 */}
)}
); }